perm filename XMPLES.DOC[P,JRA] blob
sn#115472 filedate 1974-08-09 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00009 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 BOLTING A FROB ONTO A BEAM
C00006 00003 ***** EXAMPLE 1 *****
C00010 00004 ***** EXAMPLE 2 *****
C00020 00005 **RCB** my understanding of macros vs. library routines:
C00025 00006 ***** EXAMPLE 3 *****
C00033 00007 (cont)
C00041 00008 ***** EXAMPLE 4 *****
C00048 00009 Experimental syntax etc. used in these examples
C00051 ENDMK
C⊗;
BOLTING A FROB ONTO A BEAM
This is intended to be a series of progressively more complex
examples which demonstrate some of the features in HAL, including
ATTACHMENT, control structure, macros, and library routines. All of
the examples have essentially the same goal: bolt a frob to a beam.
Each example takes into account more possibilities or contains a
different way of expressing the same thing.
The initial and final attachment structures are:
INITIAL: TABLE FINAL: TABLE
YELLOW YELLOW
BLUE BLUE
BEAM BEAM
BEAM_HOLE BEAM_HOLE
FROB FROB
FROB_HOLE FROB_HOLE
FROB_GRASP FROB_GRASP
BOLT BOLT
The initial structure can be created by the following declarations.
There will eventually be a way of interacting with the HAL monitor to
initialize frame values, either by reading an "object description"
(which might have come from the designer) or by manually positioning
the arm at the desired positions. There may very well also be some
way of running a HAL program until it requires an UNDEFINED value
(for a frame, scalar, vector, ...) and have the monitor prompt the
user for the desired values.
FRAME BEAM, BEAM_HOLE, FROB, FROB_HOLE, FROB_GRASP, BOLT;
UNITS CENTIMETERS, BOLLES, DEGREES;
BEAM ← [(30 24.2 0) : (0 0 90)];
BEAM_HOLE ← [(5.1 0 15) : (90 0 90)] WRT BEAM;
**RCB** remember that WRT is really an alternative way of saying a PREmultiply
when it is dealing with a frame and a transform ... actually it can
be thought of that way for vectors too: Z WRT BEAM is equivalent
to BEAM * Z ... or Z ∂ ORIENT(BEAM)
ATTACH BEAM_HOLE TO BEAM;
ASSERT (DEPROACH BEAM_HOLE (0 0 -3));
COMMENT this replaces the default DEPROACH (which is (0 0 3) WRT TABLE)
with a (0 0 -3) WRT BEAM_HOLE ... notice that the WRT is understood;
FROB ← [(20 40 0) : (0 0 90)];
FROB_HOLE ← [(5.1 2 0) : (180 0 90)] WRT FROB;
ATTACH FROB_HOLE TO FROB;
FROB_GRASP ← [(0 1.5 5) : (-90 0 0)] WRT FROB;
ATTACH FROB_GRASP TO FROB;
BOLT ← [(30 60 5) : (180 0 90)];
COMMENT the bolt is assumed to be sticking up out of a dispenser;
***** EXAMPLE 1 *****
The task involves the following steps:
(1) have the YELLOW arm pick up the FROB and position
it next to the BEAM so that the holes line up
(2) have the BLUE arm pick up the bolt and insert
it in the hole (in this example it is not screwed
in ... a later example will use a socket driver
to tighten the bolt)
(3) have both arms return to park
The FROB is assumed to be 1cm thick , and the BOLT 4cm long.
The following program is a straightforward way to express the motions
to carry out the task. Everything is assumed to be in the right
place and virtually every motion is assumed to accomplish the desired
effect. For example, this program assumes that the arm is accurate
enough to align the FROB_HOLE with the BEAM_HOLE and to insert the
BOLT without hitting the side or binding. Later examples will take
this type of errors into account.
OPERATE YFINGERS WITH OPENING=2;
MOVE YELLOW TO FROB_GRASP;
CENTER YELLOW;
ATTACH FROB TO YELLOW;
COMMENT this does not have to be RIGIDLY attached because any MOVE
no matter how it is specified (eg. MOVE FROB_HOLE ...)
is understood to move the arm which automatically updates anything
attached to that arm ... notice that in particular, this is
quite different from:
ATTACH FROB TO YELLOW;
FROB_HOLE ← BEAM_HOLE;
This would change the value of FROB_HOLE and the relative
position between FROB and FROB_HOLE, but leave YELLOW and FROB
unchanged.
MOVE FROB_HOLE TO BEAM_HOLE;
COMMENT notice that the FROB approaches the BEAM from the side
(not from above) because BEAM_HOLE has a special DEPROACH
... in this example the FROB is assumed to go right next
to the BEAM;
OPERATE BFINGERS WITH OPENING=1;
MOVE BLUE TO BOLT;
COMMENT assuming there is no trouble of collision;
CENTER BLUE;
MOVE BOLT TO BEAM_HOLE + (0 0 -5.3) WRT BEAM_HOLE;
COMMENT this should position the bolt .3 centimeter off of the FROB;
MOVE BLUE TO ⊗ + (0 0 5) WRT BEAM_HOLE
USING FREE=(X WRT BLUE), FREE=(Y WRT BLUE)
ON FORCE(Z WRT BLUE) > 60 DO SUCCEED;
COMMENT the arm stops when the bolt hits the bottom of the hole;
OPERATE YFINGERS WITH OPENING = 1;
DETACH FROB FROM YELLOW;
ATTACH FROB TO BEAM;
MOVE YELLOW TO YPARK;
OPERATE BFINGERS WITH OPENING = 1;
DETACH BOLT FROM BLUE;
ATTACH BOLT TO BEAM;
MOVE BLUE TO BPARK;
OUTPUT("FINISHED");
***** EXAMPLE 2 *****
This version adds a number of checks (and some automatic recoveries)
for possible run-time errors, such as not inserting the BOLT. It
also utilizes the COBEGIN ... COEND capability to describe
simultaneous (unordered, independent) actions. Thus, the Yellow arm
can be picking up the FROB and positioning it near the BEAM while the
Blue arm is picking up the BOLT. The collision avoiding is currently
the responsibility of the user.
COBEGIN
BEGIN "PICK UP FROB BY YELLOW"
OPERATE YFINGERS WITH OPENING=1;
MOVE YELLOW TO FROB_GRASP;
CENTER YELLOW
ON OPENING = 0 DO
**RCB** can I qualify OPENING OF YELLOW? **RCB**
BEGIN "MISSED FROB"
STOP YELLOW;
SCALAR FLAG;
COMMENT open the fingers and move away a little to give the
operator some room to insert the FROB;
OPERATE YFINGERS WITH OPENING=2;
GO YELLOW TO ⊗ + 3*Z;
OUTPUT("THE FROB IS MISSING ... POSITION IT AND TYPE `1'
TO TRY AGAIN");
READ(FLAG);
IF FLAG ≠ 1 THEN ABORT;
COMMENT this stops everything, saves the world, and forces
the operator to deal with the problem at monitor level,
possibly investigating the saved information, reinitializing
the world to some previous state and restarting, etc;
GO YELLOW TO FROB_GRASP;
CENTER YELLOW
ON OPENING=0 DO ABORT; COMMENT giving up after second try;
END "MISSED FROB";
ASSERT YELLOW = #(FROB_GRASP);
COMMENT this tells the compiler that the Yellow arm can be
assumed to be at FROB_GRASP however control got here ...
possibly moving away and retrying the grasp ... currently
#(FROB_GRASP) is needed to specify the planning value of
FROB_GRASP;
ATTACH FROB TO YELLOW;
COMMENT at compile time this sets up the attach structure using the
planning values for FROB and YELLOW to determine the relative
position of FROB to YELLOW (ie. the transform between them)
... at execution time, when the centering takes place, the
FROB may be slightly misplaced ... When the arm adjusts to
center on the FROB the attach structure remains the same, but
the runtime correction takes care of the difference between
the planned arm position and the actual position ... the effect
is that the FROB is assumed to be attached to the arm as planned
and the MOVE FROB_HOLE TO BEAM_HOLE ... statement will work
as planned (but the trajectory for the arm getting there is
slightly perturbed because it starts in a slightly different
place) ... If the user wants to change the relative position
of the FROB with respect to the arm, she has to use the
ATTACH FROB TO YELLOW BY T1 statement and explicitly change
the value of T1;
MOVE FROB_HOLE TO BEAM_HOLE + (0 0 1.3) WRT BEAM_HOLE;
COMMENT this positions the FROB just off of the BEAM ... the
next move pushes the FROB up against the BEAM;
GO YELLOW TO ⊗ + (0 0 .5) WRT BEAM_HOLE
ON FORCE(Z WRT BEAM_HOLE) > 50 DO SUCCEED
ON REACHING_DESTINATION DO ABORT;
COMMENT give up ... what operator communication is necessary?;
really would like a nice way of giving the operator another chance
or a set (possibly automatically set up) of possible actions ...
move out of the way a little and proceed ... go on a little
farther in the same motion (expecting it to succeed) ...;
END "PICK UP FROB BY YELLOW";
BEGIN "PICK UP BOLT BY BLUE"
COMMENT meanwhile the BLUE arm can be picking up the BOLT;
OPERATE BFINGERS WITH OPENING=1;
MOVE BLUE TO BOLT;
CENTER BLUE; COMMENT assume everything is OK;
END "PICK UP BOLT BY BLUE";
COEND;
COMMENT ... so now the FROB is positioned next to the BEAM and the BLUE arm
is holding the BOLT;
MOVE BOLT TO BEAM_HOLE + (0 0 -5.3) WRT BEAM_HOLE; COMMENT this should
position the bolt .3 centimeter off of the FROB;
COMMENT now begin a search just in case the BOLT doesn't immediately go in the
hole ... it makes .2cm steps around in a spiral ... if the BOLT does not
go in within nine tries, the whole thing is aborted;
FRAME SET; SCALAR N; COMMENT N is the number of attempts;
N ← 0;
SET ← BLUE; COMMENT save initial arm position;
SEARCH BLUE
INCREMENT .2;
NORMAL_TO Z WRT BEAM_HOLE;
REPEATING
BEGIN "INSERTING"
MOVE BLUE TO ⊗ + (0 0 1.6) WRT BEAM_HOLE
ON FORCE(Z WRT BEAM_HOLE) > 60 DO
BEGIN "MISSED AGAIN"
STOP BLUE;
N ← N + 1;
GO BLUE TO SET;
END "MISSED AGAIN"
ON N > 9 DO
BEGIN "TOO MANY MISSES, GIVE UP"
OUTSTR("CAN'T SEEM TO GET THE BOLT IN THE HOLE");
ABORT;
END "TOO MANY MISSES, GIVE UP"
ON REACHING_DESTINATION DO SUCCEED;
END;
**RCB** what is the planning value after a search? need an assert? or
will the compiler assume that the first try succeeds ... seems OK;
ASSERT BLUE = BEAM_HOLE + (0 0 3.7) WRT NBEAM_HOLE;
COMMENT expect to have the bolt (which is 4 cm) .3 cm into the hole;
GO BLUE TO [(0 0 4):(0 0 90)] WRT ⊗
USING FREE=(X WRT BLUE), FREE=(Y WRT BLUE)
ON FORCE(Z WRT BLUE) > 60 DO SUCCEED;
COMMENT notice that there are several ways of saying "move
forward 4cm and twist 90 degrees about the Z vector of
the hand":
(1) [(0 0 4):(0 0 90)] WRT ⊗
(2) BLUE * [(0 0 4):(0 0 90)]
remember that the rotation (0 0 90) is done first
(3) ⊗*[(0 0 4):(0 0 0)]*[(0 0 0):(0 0 90)];
COBEGIN "DISENGAGE"
BEGIN "YELLOW"
OPERATE YFINGERS WITH OPENING = 1;
DETACH FROB FROM YELLOW;
ATTACH FROB TO BEAM;
MOVE YELLOW TO YPARK;
END "YELLOW";
BEGIN "BLUE"
OPERATE BFINGERS WITH OPENING = 1;
DETACH BOLT FROM BLUE;
ATTACH BOLT TO BEAM;
MOVE BLUE TO BPARK;
END "BLUE";
COEND "DISENGAGE";
OUTPUT("FINISHED");
**RCB** my understanding of macros vs. library routines:
macros are expanded by the parser ... hence their "parameters"
consist of only strings ... Their expansion is a straight
string substitution ... there is no way within a macro to
do conditional expansion based upon the strings passed in
as a parameter values ... ie. you can't do:
MACRO CLOSE(THE_ARM, THICKNESS) =
⊂IFC THE_ARM = "YELLOW" THENC
OPERATE YFINGERS WITH OPENING = THICKNESS;
ELSEC
OPERATE BFINGERS WITH OPENING = THICKNESS; ;C ⊃
Library routines, on the other hand, are expanded one level
further along in the compilation process and have the symbol
table available ... and hence NAMES and planning VALUES for
all of the frames, vectors, etc. The compile time IF can
do conditional "expansion" based upon these values, the
current attach structure, and the values of compile time
variables (which can be any string of tokens) ... the remaining
questions are (1) where can COMPILE IF's occur? and (2) how
do these interact with COMPILE_TIME variables (which can only
`expand' into tokens), but they can be used anywhere a token
is legal? Thus, is it possible to write the following type
of code:
COMPILE_TIME X, Y;
X <≡ <USING FREE=Z>;
Y <≡ 1;
COMPILE IF #(Y) THEN
BEGIN MOVE YELLOW TO Q; END
ELSE
BEGIN MOVE YELLOW TO Q
#(X);
END;
COMPILE_TIME OBJECT_1, OBJECT_2;
ATTACH #(OBJECT_1) TO #(OBJECT_2);
The only slightly irregular thing is the handling of library
routine parameters. In effect the parameter values are
"names" which are substituted in for the corresponding
parameter names. The interpretation of whether the name
should be left as a name (as in ATTACH X TO YELLOW) or
expanded into its value (as in MOVE YELLOW TO X) is
determined by the context. Compile time variables can also be
passed as parameters. Thus, the following is apparently legal:
X <≡ <USING FREE=Z>;
MAKE_LIBRARY Q(COMPILE_TIME P);
BEGIN
MOVE YELLOW TO ⊗ + (0 0 4)
#(#(P));
END;
Which presumably would expand into:
MOVE YELLOW TO ⊗ + (0 0 4)
USING FREE=Z;
In all of this I am assuming that the syntax for macros and
library routines is:
a definition: DEFINE <macro name> ( <list of parameter type-name pairs> )
= ⊂ <macro body> ⊃ ;
a call: <macro name> ( <list of quoted strings> ) ;
a definition: MAKE_LIBRARY <name> ( <list of parameter type-name pairs> )
BEGIN <body> END ;
a call: <name> ( <list of parameter name-value pairs> |
<list of parameter values> ) ;
With these things in mind, the following represent some
attempts at reasonable syntax for macros (which can't expand
conditionals) and library routines (which can pass tokens
around)
***** EXAMPLE 3 *****
This example employs a macro to simplify definitions, a macro to
shorten the code for searching, and a library routine to GRASP
things. The library routine is supposed to cover a number of
possibilities and provide for a number of parameters. Since library
routines can be called with a subset of their parameters filled in,
the routine's flexibility is not oppressive for those users who just
want to do something simple. Finally, the whole task is made into a
library routine so it can be `called' (ie. expanded) as a subtask
from a higher level task.
A few little macros to change the conventions for defining macros
DEFINE MACRO = ⊂DEFINE⊃;
DEFINE BEGIN_MACRO = ⊂= ⊂⊃;
DEFINE END_MACRO = ⊂⊃⊃⊃;
**RCB** How do you include a `⊃' in a macro??? can quotes be alternative
macro delimiters ... or use SAIL's convention of ⊃⊃ within a
macro indicates a single ⊃ ... probably a better idea
MACRO DEFINE_WRT(NEW_FRAME, MAIN_FRAME, POSITION)
BEGIN_MACRO
NEW_FRAME ← POSITION WRT MAIN_FRAME;
ATTACH NEW_FRAME TO MAIN_FRAME;
END_MACRO;
A typical call might be (assuming that quotes delimit parameter values):
DEFINE_WRT("FROB_HOLE", "FROB", "[(5.1 2 0) : (180 0 90)]");
which would expand into:
FROB_HOLE ← [(5.1 2 0) : (180 0 90)] WRT FROB;
ATTACH FROB_HOLE TO FROB;
The following macro produces a string of tokens which imply a compile
time check on the value of the conditional expanded by the parameter
RIGID. If RIGID is a "1" (ie. true) the token sequence which rigidly
attaches the new frame to the main frame is used.
MACRO DEFINE_WRT(NEW_FRAME, MAIN_FRAME, POSITION, RIGID)
BEGIN_MACRO
NEW_FRAME ← POSITION WRT MAIN_FRAME;
COMPILE IF RIGID THEN ATTACH NEW_FRAME TO MAIN_FRAME RIGIDLY
ELSE ATTACH NEW_FRAME TO MAIN_FRAME;
END_MACRO;
Another, more complicated macro ... one to condense a normal search
MACRO NORMAL_SEARCH(THE_ARM, INCREM, DIST_FWD, STOPPING_FORCE, NUM_TRIES)
BEGIN_MACRO
BEGIN COMMENT this BEGIN is part of the macro code;
FRAME SET; SCALAR N; COMMENT N is the number of attempts;
N ← 0;
SET ← THE_ARM; COMMENT save initial arm position;
SEARCH THE_ARM
INCREMENT INCREM
NORMAL_TO Z WRT THE_ARM;
REPEATING
BEGIN "INSERTION"
MOVE THE_ARM TO ⊗ + (0 0 DIST_FWD) WRT THE_ARM
ON FORCE(Z WRT THE_ARM) > STOPPING_FORCE DO
BEGIN "MISSED AGAIN"
STOP THE_ARM;
N ← N + 1;
IF N > NUM_TRIES THEN
BEGIN "TOO MANY MISSES"
OUTSTR("GIVING UP ON THE SEARCH");
ABORT;
END "TOO MANY MISSES";
GO THE_ARM TO SET;
END "MISSED AGAIN"
ON REACHING_DESTINATION DO SUCCEED;
END "INSERTION";
ASSERT THE_ARM = #(SET) + (0 0 (DIST_FWD - 1));
COMMENT this changes the compiler's view to believe that the arm
succeeds on the first attempt, BUT that it does NOT go
as far as DIST_FWD ... possibly more realistic;
END;
END_MACRO;
A typical call would be:
NORMAL_SEARCH("YELLOW", ".2", "1.6", "60", "9");
The above macro could easily be made into a library routine as follows:
MAKE_LIBRARY NORMAL_SEARCH(FRAME THE_ARM; SCALAR INCREM, DIST_FWD,
STOPPING_FORCE, NUM_TRIES(9));
BEGIN
...
END;
The corresponding call:
NORMAL_SEARCH(YELLOW, .2, 1.6, 60, 9);
The "9" is a default value if no value is specified in the call. Thus, by
naming the parameters the same call can be made by:
NORMAL_SEARCH(THE_ARM=YELLOW, DIST_FWD=1.6, STOPPING_FORCE=60,
INCREM=.2);
(cont)
Now for a library routine which GRASPS things ... it uses various
parameters to make various checks, to approach in a special way, etc.
MAKE_LIBRARY GRASP(COMPILE_TIME SPECIAL_DEP(NIL), A_VIA(NIL), SPECIAL_APP(NIL),
THE_FINGERS( YFINGERS ),
OPEN_AT( ON REACHING_DEPARTURE DO );
FRAME THE_ARM(YELLOW), OBJECT, GRASP_POINT;
SCALAR DEP_OPENING, APP_OPENING(15), THICKNESS(0));
**RCB** the defaults are simply tokenized and filled in if not explicitly
assigned (ie. "DEFINED") in the call ... the predicate DEFINED(...)
built-in so compile time checks can ask if a value was filled in
BEGIN "GRASP"
COMPILE IF DEFINED(DEP_OPENING) THEN
OPERATE YFINGERS WITH OPENING=DEP_OPENING;
MOVE YELLOW TO GRASP_POINT
#(SPECIAL_DEP)
#(A_VIA)
#(SPECIAL_APP)
#(OPEN_AT)
OPERATE #(THE_FINGERS) WITH OPENING=APP_OPENING;
CENTER THE_ARM
ON OPENING < THICKNESS DO
BEGIN "MISSED OBJECT"
STOP THE_ARM;
SCALAR FLAG;
OPERATE THE_FINGERS WITH OPENING=APP_OPENING;
GO THE_ARM TO (COMPILE IF DEFINED(SPECIAL_APP) THEN
(SPECIAL_APP WRT ⊗) ELSE DEPARTURE(OBJECT));
**RCB** is DEPARTURE(OBJECT) fair?
OUTPUT("GRASP FAILED ... TYPE A `1' TO RETRY");
READ(FLAG);
COMMENT this is simply "wait for proceed";
IF FLAG ≠ 1 THEN ABORT;
GO THE_ARM TO OBJECT;
CENTER THE_ARM
ON OPENING < THICKNESS DO ABORT;
END "MISSED OBJECT";
ASSERT THE_ARM = GRASP_POINT;
ATTACH OBJECT TO THE_ARM;
END "GRASP";
Finally, a library routine to carry out the "bolt the frob to the beam"
task ... of course, using all of the above macros and library routines.
MAKE_LIBRARY BOLT_ON_FROB;
BEGIN "WHOLE TASK"
COMMENT assume that the two arms are at their park positions with
their hands empty;
COBEGIN
BEGIN "PICK UP FROB WITH YELLOW"
GRASP(GRASP_POINT=FROB_GRASP, OBJECT=FROB, APP_OPENING=2);
MOVE FROB_HOLE TO BEAM_HOLE + (0 0 1.3) WRT BEAM_HOLE;
GO YELLOW TO ⊗ + (0 0 .5) WRT BEAM_HOLE
ON FORCE(Z WRT BEAM_HOLE) > 50 DO SUCCEED
ON REACHING_DESTINATION DO ABORT;
END "PICK UP FROB WITH YELLOW;
BEGIN "PICK UP BOLT WITH BLUE"
GRASP(THE_ARM=BLUE, THE_FINGERS=BFINGERS, OBJECT=BOLT,
GRASP_POINT=BOLT, APP_OPENING=2);
END "PICK UP BOLT WITH BLUE";
COEND;
MOVE BOLT TO BEAM_HOLE + (0 0 -5.3) WRT BEAM_HOLE;
NORMAL_SEARCH(BLUE, .2, 1.6, 60, 9);
COMMENT assume that the bolt is now in the hole;
MOVE BLUE TO [(0 0 4):(0 0 90)] WRT ⊗
ON FORCE(Z WRT BLUE) > 60 DO SUCCEED;
COBEGIN "DISENGAGE"
BEGIN "YELLOW"
OPERATE YFINGERS WITH OPENING = 1;
DETACH FROB FROM YELLOW;
ATTACH FROB TO BEAM;
MOVE YELLOW TO YPARK;
END "YELLOW";
BEGIN "BLUE"
OPERATE BFINGERS WITH OPENING = 1;
DETACH BOLT FROM BLUE;
ATTACH BOLT TO BEAM;
MOVE BLUE TO BPARK;
END "BLUE";
COEND "DISENGAGE";
END "WHOLE TASK";
***** EXAMPLE 4 *****
In this version of the task the BLUE arm picks up a power driver
(which has the appropriate socket on the end), picks up a screw
magnetically, inserts the screw in the hole, and screws in the screw.
Provisions are made for some of the more subtle aspects of assembly
such as freeing the FROB while trying to insert the screw in the hole
and changing the speed of the driver dynamically.
Freeing the YELLOW arm so the FROB can accommodate slightly along the
surface of the BEAM as the BLUE arm tries to insert the screw:
MOVE BOLT TO BEAM_HOLE + (0 0 -5.3) WRT BEAM_HOLE;
COMMENT remember that the BOLT is in the BLUE hand;
MOVE YELLOW TO ⊗
USING FREE=(X WRT BEAM_HOLE), FREE=(Y WRT BEAM_HOLE)
ON DURATION > 0 DO
BEGIN "INSERTION"
COMMENT notice that "DURATION > 0" is an approximation
to simultaneous motions;
NORMAL_SEARCH(BLUE, .2, 1.6, 60, 9);
COMMENT assume that the bolt is now in the hole;
MOVE BLUE TO [(0 0 4):(0 0 90)] WRT ⊗
ON FORCE(Z WRT BLUE) > 60 DO SUCCEED;
END "INSERTION";
Without the SEARCH this could be accomplished in "weak" synchrony.
MOVE BOLT TO BEAM_HOLE + (0 0 -5.3) WRT BEAM_HOLE;
MOVE {BLUE, YELLOW}
TO {⊗ + (0 0 1.6) WRT BLUE, *}
USING FREE = {*, (X WRT BEAM_HOLE))
USING FREE = {*, (Y WRT BEAM_HOLE))
ON {FORCE(Z WRT BLUE) > 60, *} DO ABORT;
But to include the SEARCH this gets awkward. Either parallel,
simultaneously beginning blocks should be allowed, or the
NORMAL_SEARCH macro has to be rewritten to deal with both arms
simultaneously. This type of coordination also comes up in a number
of other places. For example, if you want to operate a device (eg.
the DRIVER) and move an arm or camera "at the same time."
Simultaneous blocks do, however, present some problems in timing when
one of the blocks contains "interpreters." It is not at all clear how
fast interpreters are run with respect to moving an arm.
MOVE BOLT TO BEAM_HOLE + (0 0 -5.3) WRT BEAM_HOLE;
SIMULTANEOUS BEGIN
BEGIN
MOVE YELLOW TO ⊗;
END;
BEGIN
NORMAL_SEARCH(BLUE, .2, 1.6, 60, 9);
COMMENT assume that the bolt is now in the hole;
MOVE BLUE TO [(0 0 4):(0 0 90)] WRT ⊗
ON FORCE(Z WRT BLUE) > 60 DO SUCCEED;
END;
SIMULTANEOUS END;
Consider the problem of screwing in a screw and checking to make sure
that it does not bind. If, after a short time, the screw does not
bind, the speed of the DRIVER can be increased. However, if it does
bind, everything should stop and the DRIVER should be reversed to try
to unbind the screw.
SCALAR SP, FLAG;
SP ← 30;
FLAG ← 1;
WHILE FLAG DO
BEGIN "SCREW LOOP"
OPERATE DRIVER
VELOCITY = SP
ON DURATION > 0 DO
BEGIN "EXERT DOWNWARD FORCE"
MOVE BLUE TO ⊗
USING FREE=(Z WRT BLUE)
USING FORCE=((0 0 40) WRT BLUE)
"BIND" ON TORQUE(Z WRT BLUE) > 80 DO
BEGIN
DISABLE "CATCH_OK";
STOP BLUE;
STOP DRIVER;
COMMENT try to unbind by reversing the driver;
SP ← -60;
OPERATE DRIVER
VELOCITY = SP
ON DURATION > 0 DO
BEGIN "UPWARD FORCE"
MOVE BLUE TO ⊗
USING FREE=(Z WRT BLUE)
USING FORCE=((0 0 -40) WRT BLUE)
"OUT_OK" ON FORCE(Z WRT BLUE)<20 DO
BEGIN
DISABLE "TOO_MUCH_TIME";
STOP DRIVER;
STOP BLUE;
COMMENT leave FLAG true for retry;
END
"TOO_MUCH_TIME" ON DURATION>5 DO ABORT;
END "UPWARD FORCE";
***** this isn't very nice ...
I'm leaning toward simultaneous begins RCB
END
"CATCH_OK" ON DURATION > 3 DO
BEGIN
DISABLE "BIND";
ENABLE "TORQUED_IN_OK";
SP ← 60; COMMENT maybe this should be CRITICAL;
END;
"TORQUED_IN_OK" ON TORQUE(Z WRT BLUE) > 80 DO
BEGIN
STOP DRIVER;
STOP BLUE;
FLAG ← 0; COMMENT indicating no retry;
END;
END "EXERT DOWNWARD FORCE";
END "SCREW LOOP";
Experimental syntax etc. used in these examples
MOVE BOLT TO BEAM_HOLE - (0 0 5.3) WRT BEAM_HOLE;
COMMENT subtraction allowed???;
What is the statement status of a COMPILE IF ... can it be an expression?
DEFAULT THE_ARM, SPECIAL_DEP, A_VIA, SPECIAL_APP, OBJECT = NIL;
a new construct to initial parameters possibly ... NIL means that
there is no initialization AND this can the checked for at
compile time to see if something other than NIL has been assigned
If something is used and it has a NIL value the compiler should
give and error message
ABORT ... jumps out of current program ... back to the monitor
level ... possibly saving the world as it believes it is
ON REACHING_DESTINATION DO ... a way of distinguishing completing
a MOVE and SUCCESS which gets you out of REPEATING etc.
Z WRT BLUE ... as a more readable way of expressing
Z ∂ ORIENT(BLUE) ... maybe there should be a better notation
MOVE's within ON's as long as there is a STOP preceeding it ... to
move the same arm
MOVE BLUE TO [(0 0 4):(0 0 90)] WRT ⊗
COMMENT how does one say move forward 4cm and twist 90 degrees
about the approach vector of the hand? remember that the rotation
is done first;
ASSERT THE_ARM = #(SET) + (0 0 (DIST_FWD - 1)); ... the compiler has to
expand the macro constant DIST_FWD and do the subtraction
to compute the actual assertion value ... can normal vectors
contain expressions???
may not be able to do this because SET is not a constant
presumably this works with the #(...)
More generally ... what are the compile-time world implications of a
SEARCH, CENTER, LOOP, ...???????